using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Security;
namespace Net35.Xrm.Sdk
{
	internal sealed class AppDomainBasedKnownProxyTypesProvider : KnownProxyTypesProvider
	{
		private static Dictionary<string, Type> _nameMap;
		private static Dictionary<Type, string> _typeMap;
		private Dictionary<string, Type> _currentMap;
		[SecuritySafeCritical]
		internal AppDomainBasedKnownProxyTypesProvider()
		{
			AppDomainBasedKnownProxyTypesProvider._nameMap = new Dictionary<string, Type>();
			AppDomainBasedKnownProxyTypesProvider._typeMap = new Dictionary<Type, string>();
			AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(this.CurrentDomain_AssemblyLoad);
			base.InitializeLoadedAssemblies();
		}
		public override Type GetTypeForName(string name, Assembly notUsed)
		{
			if (AppDomainBasedKnownProxyTypesProvider._nameMap.ContainsKey(name))
			{
				return AppDomainBasedKnownProxyTypesProvider._nameMap[name];
			}
			lock (KnownProxyTypesProvider.ThisLock)
			{
				if (AppDomainBasedKnownProxyTypesProvider._nameMap.ContainsKey(name))
				{
					return AppDomainBasedKnownProxyTypesProvider._nameMap[name];
				}
			}
			return null;
		}
		public override string GetNameForType(Type type)
		{
			if (AppDomainBasedKnownProxyTypesProvider._typeMap.ContainsKey(type))
			{
				return AppDomainBasedKnownProxyTypesProvider._typeMap[type];
			}
			lock (KnownProxyTypesProvider.ThisLock)
			{
				if (AppDomainBasedKnownProxyTypesProvider._typeMap.ContainsKey(type))
				{
					return AppDomainBasedKnownProxyTypesProvider._typeMap[type];
				}
			}
			return null;
		}
		protected override void AddTypeMapping(Assembly assembly, Type type, string proxyName)
		{
			if (AppDomainBasedKnownProxyTypesProvider._nameMap.ContainsKey(proxyName))
			{
				throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "A proxy type with the name {0} has been defined by another assembly. Current type: {1}, Existing type: {2}", new object[]
				{
					proxyName,
					type.AssemblyQualifiedName,
					AppDomainBasedKnownProxyTypesProvider._nameMap[proxyName].AssemblyQualifiedName
				}), proxyName);
			}
			if (this._currentMap.ContainsKey(proxyName))
			{
				throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "A proxy type with the name {0} has been defined by an assembly. Current type: {1}, Existing type: {2}", new object[]
				{
					proxyName,
					type.AssemblyQualifiedName,
					this._currentMap[proxyName].AssemblyQualifiedName
				}), proxyName);
			}
			this._currentMap.Add(proxyName, type);
		}
		protected override void OnBeginLoadTypes(Assembly targetAssembly)
		{
			this._currentMap = new Dictionary<string, Type>();
		}
		protected override void OnEndLoadTypes()
		{
			if (this._currentMap != null && this._currentMap.Count > 0)
			{
				foreach (string current in this._currentMap.Keys)
				{
					AppDomainBasedKnownProxyTypesProvider._nameMap[current] = this._currentMap[current];
					AppDomainBasedKnownProxyTypesProvider._typeMap[this._currentMap[current]] = current;
				}
			}
			this._currentMap = null;
		}
		protected override void OnErrorLoadTypes()
		{
			this._currentMap = null;
		}
		private void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
		{
			base.RegisterAssembly(args.LoadedAssembly);
		}
	}
}
